home *** CD-ROM | disk | FTP | other *** search
/ NeXT Education Software Sampler 1992 Fall / NeXT Education Software Sampler 1992 Fall.iso / Programming / Source / WAIS / next-ui / IconWellControl.m < prev    next >
Encoding:
Text File  |  1992-07-27  |  4.4 KB  |  174 lines

  1. // IconWellControl.m
  2. //
  3. // Free software created 1 Feb 1992
  4. // by Paul Burchard <burchard@math.utah.edu>.
  5.  
  6. #import "IconWellControl.h"
  7. #import "IconWell.h"
  8. #import "DragDrop.h"
  9. #import <appkit/appkit.h>
  10. #import <objc/Storage.h>
  11. #import <objc/HashTable.h>
  12.  
  13.  
  14. @implementation IconWellControl
  15.  
  16. static id wellSpeaker;
  17. static id convertWindowToControl;
  18.  
  19. + initialize
  20. {
  21.     if(self == [IconWellControl class])
  22.     {
  23.         wellSpeaker = [[Speaker alloc] init];
  24.     convertWindowToControl =
  25.         [[HashTable alloc] initKeyDesc:"@" valueDesc:"@"];
  26.     }
  27.     return self;
  28. }
  29.  
  30. + controlFor:theWindow
  31. {
  32.     return (id)[convertWindowToControl valueForKey:(void *)theWindow];
  33. }
  34.  
  35. - listen:sender
  36. {
  37.     // Tell WorkSpace we want icon-dragging.
  38.     if(isListening) return self;
  39.     if(!window) return nil;
  40.     NXConvertWinNumToGlobal([window windowNum], &globalWindowNum);
  41.     if(![wellSpeaker setSendPort:NXPortFromName(NX_WORKSPACEREQUEST, NULL)])
  42.     return nil;
  43.     if(0 != [wellSpeaker registerWindow:globalWindowNum
  44.     toPort:[wellListener listenPort]])
  45.     return nil;
  46.     [wellListener setDelegate:self];
  47.     isListening = YES;
  48.     return self;
  49. }
  50.  
  51. - initWindow:theWindow
  52. {
  53.     char portName[1024];
  54.     
  55.     [super init];
  56.     window = theWindow;
  57.     wellListener = [[Listener alloc] init];
  58.     sprintf(portName, "IconWellControlPort-%ld", (long)[self self]);
  59.     if(0 != [wellListener checkInAs:portName]) return nil;
  60.     [wellListener addPort];
  61.     newIconPath = [[Storage alloc] initCount:0 elementSize:sizeof(char) description:"c"];
  62.     [convertWindowToControl insertKey:(void *)theWindow value:(void *)self];
  63.     [self listen:self];
  64.     return self;
  65. }
  66.  
  67. - free
  68. {
  69.     if(window) [convertWindowToControl removeKey:(void *)window];
  70.     [wellListener free];
  71.     [newIconPath free];
  72.     [newIconImage free];
  73.     return [super free];
  74. }
  75.  
  76. - (const char *)newIconPath
  77. {
  78.     return (const char *)[newIconPath elementAt:0];
  79. }
  80.  
  81. - (int)iconEntered:(int)windowNum at:(double)x :(double)y
  82.     iconWindow:(int)iconWindowNum iconX:(double)iconX iconY:(double)iconY
  83.     iconWidth:(double)iconWidth iconHeight:(double)iconHeight
  84.     pathList:(char *)pathList
  85. {
  86.     int i, n;
  87.     id list;
  88.     NXSize size;
  89.  
  90.     // Create temp NXImage to hold dragged icon.
  91.     // NOTE: newIconImage is only freed beforehand if it still has temp name.
  92.     if(!pathList) return 0;
  93.     size.width = size.height = 48.0;
  94.     [[NXImage findImageNamed:newIconName] free];
  95.     newIconImage = [[NXImage alloc] initSize:&size];
  96.     [newIconImage lockFocus];
  97.     copyIconPicture(iconWindowNum,
  98.         (float) iconX, (float) iconY, (float) iconWidth, (float) iconHeight);
  99.     [newIconImage unlockFocus];
  100.     [newIconImage setName:newIconName];
  101.     
  102.     // Temporarily stash new path.
  103.     [newIconPath setNumSlots:(strlen(pathList)+1)];
  104.     strcpy((char *)[newIconPath elementAt:0], pathList);
  105.  
  106.     // Accept message, and forward to all IconWells in this Window.
  107.     list = [IconWell wellListFor:window];
  108.     n = [list count];
  109.     for(i=0; i<n; i++)
  110.         [[list objectAt:i] iconEntered:windowNum at:x :y
  111.         iconWindow:iconWindowNum iconX:iconX iconY:iconY
  112.         iconWidth:iconWidth iconHeight:iconHeight
  113.         pathList:pathList];
  114.     return 0;
  115. }
  116.  
  117. - (int)iconMovedTo:(double)x :(double)y
  118. {
  119.     int i, n;
  120.     id list;
  121.     
  122.     // Accept message, and forward to all IconWells in this Window.
  123.     list = [IconWell wellListFor:window];
  124.     n = [list count];
  125.     for(i=0; i<n; i++)
  126.         [[list objectAt:i] iconMovedTo:x :y];
  127.     return 0;
  128. }
  129.  
  130. - (int)iconExitedAt:(double)x :(double)y
  131. {
  132.     int i, n;
  133.     id list;
  134.     
  135.     // Accept message, and forward to all IconWells in this Window.
  136.     list = [IconWell wellListFor:window];
  137.     n = [list count];
  138.     for(i=0; i<n; i++)
  139.         [[list objectAt:i] iconExitedAt:x :y];
  140.     
  141.     // Get rid of temp icon and path.
  142.     [[NXImage findImageNamed:newIconName] free];
  143.     newIconImage = nil;
  144.     [newIconPath setNumSlots:0];
  145.     return 0;
  146. }
  147.  
  148. - (int)iconReleasedAt:(double)x :(double)y ok:(int *)flag
  149. {
  150.     int i, n, accepted;
  151.     id list;
  152.     
  153.     // Accept message, and forward to all IconWells in this Window.
  154.     list = [IconWell wellListFor:window];
  155.     n = [list count];
  156.     for(i=0, *flag=0, accepted=0; i<n; i++, accepted=0)
  157.     {
  158.         [[list objectAt:i] iconReleasedAt:x :y ok:&accepted];
  159.     if(accepted != 0) *flag = 1;
  160.     }
  161.  
  162.     // Get rid of temp path.
  163.     // Temp icon image is only freed if it was not accepted.
  164.     [newIconPath setNumSlots:0];
  165.     if(*flag == 0)
  166.     {
  167.     [[NXImage findImageNamed:newIconName] free];
  168.     newIconImage = nil;
  169.     }
  170.     return 0;
  171. }
  172.  
  173. @end
  174.